# -*- coding: utf-8 -*-

from __future__ import division
import Role
import ThrowIn

class Rule:
  def isChecked(self, game): pass
  def consequence(self, game): pass

class Ball(Rule):
  def isChecked(self, game):
    f = game.field
    b = game.ball
    return not f.isInTouch1(b)        \
       and not f.isInTouch2(b)        \
       and not f.isBehindGoalTeam1(b) \
       and not f.isBehindGoalTeam2(b)
       
  def consequence(self, game): game.ball.stop()

class BallInGoal(Rule):
  def isChecked(self, game):
    return not game.field.isInGoalTeam1(game.ball) \
       and not game.field.isInGoalTeam2(game.ball)

  def consequence(self, game):
    game.ball.stop()
    if game.field.isInGoalTeam1(game.ball):
      game.team2.score += 1
      # TODO: Wait 1 second
      game.throwIn = ThrowIn.BeginTeam1()
    else:
      game.team1.score += 1
      # TODO: Wait 1 second
      game.throwIn = ThrowIn.BeginTeam2()


class BallOnTouchLine(Rule):
  def isChecked(self, game):
    return (not game.field.isInTouch1(game.ball)  \
       and  not game.field.isInTouch2(game.ball)) \
        or  game.isThrowingIn

  def consequence(self, game):
    if game.ballOwner != None:
      game.ballOwner.hasTheBall = False
      game.setBallOwner(None)

    l = game.field.evaluateTouchLocation(game.ball)
    if game.lastBallOwner == None:
      raise Exception("Who threw the ball outside of the field?")

    team     = None
    sender   = None
    receiver = None
    if game.lastBallOwner in game.team1.players:
      team     = game.team2
      sender   = game.team2.getPlayerByRole(Role.Helper.MidfielderForward)
      receiver = game.team2.getPlayerByRole(Role.Helper.ForwardCenter)
    elif game.lastBallOwner in game.team2.players:
      team     = game.team1
      sender   = game.team1.getPlayerByRole(Role.Helper.MidfielderForward)
      receiver = game.team1.getPlayerByRole(Role.Helper.ForwardCenter)

    if sender == None or receiver == None:
      raise Exception("Nobody to make properly that throw-in.")

    game.throwIn = ThrowIn.Standard(sender, receiver, l, team)

class BallBehindTheGoal(Rule):
  def isChecked(self, game):
    f = game.field
    b = game.ball
    if f.isInGoalTeam1(b) or f.isInGoalTeam2(b): return True
    return (not f.isBehindGoalTeam1(b)  \
       and  not f.isBehindGoalTeam2(b)) \
        or  game.isThrowingIn

  def consequence(self, game):
    game.ball.stop()

    if game.ballOwner != None:
      game.ballOwner.hasTheBall = False
      game.setBallOwner(None)

    lBall    = None
    team     = None
    sender   = None
    receiver = None
    if game.team1.contains(game.lastBallOwner):
      if game.field.isBehindGoalTeam1(game.ball):
        lBall = game.field.evaluateCornerLocation(game.ball)
      else:
        lBall = game.field.evaluateSixMetersLocation(game.ball)
      team     = game.team2
      sender   = game.team2.getPlayerByRole(Role.Helper.MidfielderForward)
      receiver = game.team2.getPlayerByRole(Role.Helper.ForwardCenter)
    elif game.team2.contains(game.lastBallOwner):
      if game.field.isBehindGoalTeam2(game.ball):
        lBall = game.field.evaluateCornerLocation(game.ball)
      else:
        lBall = game.field.evaluateSixMetersLocation(game.ball)
      team     = game.team1
      sender   = game.team1.getPlayerByRole(Role.Helper.MidfielderForward)
      receiver = game.team1.getPlayerByRole(Role.Helper.ForwardCenter)

    if sender == None or receiver == None:
      raise Exception("Nobody to make the corner or six meters properly.")

    game.throwIn = ThrowIn.Standard(sender, receiver, lBall, team)


class Throw(Rule):
  def isChecked(self, game): return not game.isThrowingIn

  def consequence(self, game):
    if game.ballOwner == None: raise Exception("No player owns the ball.")
    for p in game.team1.players:
      self.__circle(game.ballOwner.location, game.field.width * 9 / 100, p)

  def __circle(self, location, ray, player):
    if player.location != location:
      if location.distance(player.location) < ray:
        v = location.getTranslationVector(player.location).getNormalizedVector() * ray
        player.location.locate(location + v)

class Player(Rule):
  def __init__(self): self.outsidePlayers = []
  def isChecked(self, game):
    ok = True
    for p in game.team1.players:
      if not game.field.isInTheField(p):
        self.outsidePlayers.append(p)
        ok = False
    for p in game.team2.players:
      if not game.field.isInTheField(p):
        self.outsidePlayers.append(p)
        ok = False
    return ok

  def consequence(self, game):
    for p in self.outsidePlayers:
      p.location.locate(game.field.evaluateClosestFieldLocation(p))
    self.outsidePlayers = []

class Game:
  def __init__(self): self.rules = []
  def append(self, r): self.rules.append(r)
  def areValidated(self, game):
    for r in self.rules:
      if not r.isChecked(game):
        r.consequence(game)
